package com.example.scheduling.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.concurrent.TimeUnit;

@Configuration
public class SchedulerDemo {
    // TODO 请注意，要调度的每个方法都必须具有 void 返回值并且不能接受任何参数。如果方法需要与应用程序上下文中的其他对象交互，则这些对象通常会通过依赖注入提供。


    // 您可以将 @Scheduled 注解添加到方法中，以及触发器元数据。例如，以下方法以固定的延迟每五秒（5000 毫秒）调用一次，这意味着周期是从每次先前调用的完成时间开始测量的。
    @Scheduled(fixedDelay = 5000)
    public void doSomething() {
        // 应该定期运行的东西
        System.out.println("Executing scheduled task...");
        System.out.println("Scheduled-demo-1");
    }

    // 默认情况下，毫秒将用作固定延迟、固定速率和初始延迟值的单位。如果您想使用不同的时间单位（例如秒或分钟），可以通过 @Scheduled 中的 timeUnit 属性配置此选项。
    @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS)
    public void doSomething1() {
        // 每次执行一次后，延迟 5 秒再执行

        // 应该定期运行的东西
        System.out.println("Scheduled-demo-2");
    }

    // 如果您需要固定速率执行，则可以在注解中使用 fixedRate 属性。以下方法每五秒钟（在每次调用的连续开始时间之间测量）调用一次
    @Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS)
    public void doSomething3() {
        // 每五秒执行一次

        // 应该定期运行的东西
        System.out.println("Scheduled-demo-3");
    }

    // 对于固定延迟和固定速率任务，您可以通过指示在方法第一次执行之前等待的时间来指定初始延迟
    @Scheduled(initialDelay = 1, fixedRate = 5, timeUnit = TimeUnit.SECONDS)
    public void doSomething4() {
        // 第一次执行之前等待 1 秒，然后每五秒执行一次

        // 应该定期运行的东西
        System.out.println("Scheduled-demo-4");
    }

    // 对于一次性任务，您可以只指定初始延迟，指示在预期执行方法之前等待的时间
    @Scheduled(initialDelay = 1000)
    public void doSomething5() {
        // 如果定时任务只有 initialDelay 属性，则该方法将在 1 秒后执行一次，然后就不再执行了

        // 应该定期运行的东西
        System.out.println("Scheduled-demo-5");
    }

    // 如果简单的周期性调度不够表达力，您可以提供一个cron 表达式。以下示例仅在工作日运行。您还可以使用 zone 属性指定解析 cron 表达式的时间区域。
    @Scheduled(cron="*/5 * * * * MON-FRI", zone = "Asia/Shanghai")
    public void doSomething6() {
        // 应该定期运行的东西
        System.out.println("Scheduled-demo-6");
    }
}
